<?php

declare(strict_types=1);

namespace App\Service;

/**
 * 用户信息服务类
 * 用于取得用户信息数据-较为动态的资料
 * 作者 薛原
 * 日期 2025-10-17
 */
use App\Exception\BusinessException;
use App\Lib\JWTTools;
use Hyperf\Di\Annotation\Inject;
use App\Repository\UserRepository;
use App\Repository\UserProfilesRepository;
use Psr\EventDispatcher\EventDispatcherInterface;

class UserService1
{
    #[Inject]
    private UserRepository $userRepository;
    #[Inject]
    private UserProfilesRepository $userProfilesRepository;
    #[Inject]
    private EventDispatcherInterface $eventDispatcher;
    /**
     * 创建用户
     */
    public function createUser(array $data): array
    {
        // 数据验证
        $this->validateUserData($data);

        // 业务逻辑处理
        $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        $data['email_verified_at'] = null;
        //此处注册user用户
        $data['role'] = 'user';
        // 创建用户
        $user = $this->userRepository->create($data);
        // 触发用户创建事件
        $this->eventDispatcher->dispatch(new \App\Event\UserCreated($user));

        $token = $this->generateToken($user);
        return ["user"=>$user,"token"=>$token];
    }

    /**
     * 用户登录
     */
    public function login(string $email, string $password, string $ip, $role = "user"): array
    {
        $user = $this->userRepository->findByEmail($email);

        if (!$user || !password_verify($password, $user['password'])) {
            throw new BusinessException('邮箱或密码错误');
        }
        if($user['role'] != $role){
            throw new BusinessException('角色有误');
        }
        if ($user['status'] !== 'active') {
            throw new BusinessException('账号已被禁用');
        }

        // 生成接口访问 token
        $token = $this->generateToken($user);

        // 更新登录信息
        $this->userRepository->updateLoginInfo($user['id'], $ip);

        return [
            'user' => $user,
            'token' => $token,
            'expires_in' => 7200
        ];
    }
    public function getUserById(string $id, $with_profiles = false)
    {
        $user = $this->userRepository->getDataById($id);
        if(!$user){
            throw new BusinessException('无此用户');
        }
        //需要连带资料
        if($with_profiles){
            $user['profile'] = $this->userProfilesRepository->getDataById($user['id']);
        }
        return $user;
    }
    public function updateUser(array $data,$id):void
    {
        $user = $this->getUserById($id);
        //名字相同不更新
        if($user['name'] == $data['name']){
            unset($data['name']);
        }
        $validator_result = \App\Lib\BaseValidator::make($data, [
            'name' => 'string|min:2|max:20|unique:users',
            'avatar' => 'url',
        ],[
            'name.required'=>'用户名不能为空！',
            'name.unique'=>'用户名被占用',
            'name.min'=>'用户名长度需为2-20字符！',
            'name.max'=>'用户名长度需为2-20字符！',
            'avatar.url'=>'头像格式有误！'
        ]);
        if (!$validator_result) {
            throw new BusinessException(\App\Lib\BaseValidator::$error,0 );
        }
        $this->userRepository->updateNameAndAvatar($data,$id);
    }
    private function validateUserData(array $data): void
    {
        $validator_result = \App\Lib\BaseValidator::make($data, [
            'name' => 'required|string|min:2|max:20|unique:users',
            'email' => 'required|email|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ],[
            'name.required'=>'用户名不能为空！',
            'name.min'=>'用户名长度需为2-20字符！',
            'name.max'=>'用户名长度需为2-20字符！',
            'email.required'=>'邮箱不能为空！',
            'name.unique'=>'用户名已被占用！',
            'email.email'=>'邮箱格式有误！',
            'email.unique'=>'邮箱已被占用！',
            'password.required'=>'密码不能为空',
            'password.min'=>'密码最低8个字符',
            'password.confirmed'=>'密码两次输入不一致'
        ]);
        if (!$validator_result) {
            throw new BusinessException(\App\Lib\BaseValidator::$error,0 );
        }
    }

    private function generateToken(array $user): string
    {
        return base64_encode(json_encode(['acl'=>[
            'user_id' => $user['id'],
            'email' => $user['email'],
            'role' => $user['role'],
        ]]));
    }
}